package de.popforge.audio 
{
	import __AS3__.vec.Vector;
	import de.popforge.audio.driver.AudioDriver;
	import de.popforge.audio.driver.IAudioProcessor;	

	/**
	 * @author Andre Michelle
	 */
	public class LowPassLFO
		implements IAudioProcessor 
	{
		private var _lfoPhase: Number;
		private var _lfoAdd: Number;
		
		private var _resonance: Number;
		private var _poleLVel: Number;
		private var _poleLVal: Number;
		private var _poleRVel: Number;
		private var _poleRVal: Number;
		
		private var _minFreq: Number;
		private var _maxFreq: Number;
		
		public function LowPassLFO( lfoSpeedMs: Number, resonance: Number, minFreq: Number, maxFreq: Number )
		{
			_lfoAdd = 1.0 / ( lfoSpeedMs * 44.1 ); // 1 cycle/lfoSpeedMs
			_lfoPhase = 0.0;
			_resonance = resonance;
			_minFreq = minFreq;
			_maxFreq = maxFreq;
			
			//-- 1Pole Filter (Stereo)
			_poleLVel = 0.0;
			_poleLVal = 0.0;
			_poleRVel = 0.0;
			_poleRVal = 0.0;
		}
		
		public function process( buffer: Vector.<Vector.<Number>> ): void
		{
			var leBuffer: Vector.<Number> = buffer[0];
			var riBuffer: Vector.<Number> = buffer[1];
			
			var lfoValue: Number;
			var freq: Number;
			var cutoff: Number;
			
			var i: int = 0;
			var n: int = AudioDriver.SIZE;
			
			for( ; i < n ; ++i )
			{
				//-- compute LFO (triangle)
				lfoValue = _lfoPhase < .5 ? _lfoPhase * 2.0 : 2.0 - _lfoPhase * 2.0;
				
				//-- move LFO in time
				_lfoPhase += _lfoAdd;
				if( _lfoPhase >= 1.0 ) --_lfoPhase;
				
				//-- compute cutoff coeff by exponential mapping
				freq = _minFreq * Math.exp( lfoValue * Math.log( _maxFreq / _minFreq ) );
				cutoff = Math.sin( 2.0 * Math.PI * freq / 44100 );

				_poleLVel *= _resonance;
				_poleLVel += ( leBuffer[i] - _poleLVal ) * cutoff;
				_poleLVal += _poleLVel;
				
				_poleRVel *= _resonance;
				_poleRVel += ( riBuffer[i] - _poleRVal ) * cutoff;
				_poleRVal += _poleRVel;

				leBuffer[i] = _poleLVal;
				riBuffer[i] = _poleRVal;
			}
		}

		private function tanh( x: Number ): Number
		{
			return ( 1 - ( 2 / ( Math.pow( 2.71828183, 2 * x ) + 1 ) ) );
		}
	}
}
